<?php
namespace App\Services\ImgServices;
/***
 * 图片
 *
 *
 * @author    lanhongjie <lanhj@yunys.com.cn>
 * @copyright 2016 QuanZhouYunYiShang Inc.
 */

use \App\Services\Tool\ImageProcessor\ImagickTool as ImagickTool;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class ImgTool
{
    protected $imagickTool;
    private $img_storage_absolute_dir='/data/webserver/Fashion/Fashion/public/images/';
    private static $img_storage_dir='/data/webserver/Fashion/Fashion/public/images/';
    private static $img_url_std_prefix='http://fashion.apiyys.com/images/';
    private static $MYTEE_IMG_CDN_PREFIX='http://img.mytee.cc/';
    private static $X_OSS_PROCESS='?x-oss-process=style/product-source-thumbnail';
    private static $PRODUT_THUMB_X_OSS_PROCESS='?x-oss-process=style/product-thumbnail';
    /**
     * ImgTool constructor.
     */
    public function __construct(ImagickTool $imagickTool)
    {
        $this->imagickTool=$imagickTool;
        $this->img_storage_absolute_dir=public_path('images').DIRECTORY_SEPARATOR;
    }

    /***
     * 保存图片 MD5计算图片是否重复
     * @param $img_file
     * @param int $retreturn_type  1返回img_id 其他相对路径
     * @return array|string
     */
    public function imgSave($img_file,$retreturn_type=2,$quality_compression=false){
        try{
            $image_path='';
            if(!empty($img_file)){
                $image_path=$this->imagickTool->save($img_file);
                $image_absolute_path= $this->img_storage_absolute_dir.$image_path;
                $image_path=self::saveImg2DBByImgPath($image_absolute_path);
                if($quality_compression&&!empty($image_path)){
                    $pngquant_img_path=self::imgPathPngquantAndReturnImgPath($image_path);
                    if(!empty($pngquant_img_path)){
                        $image_path=$pngquant_img_path;
                    }
                }
            }
            return $image_path;
        }catch (\Exception $e){
            Log::info($e);
            return '';
        }
    }

    /***
     * 判断图片是不是存过，并把图片对应信息存储到数据库
     * @param $image_absolute_path
     * @return bool|string
     */
    public function saveImg2DBByImgPath($image_absolute_path){
        try{
            $image_path_arr=explode('images/',$image_absolute_path);
            if(sizeof($image_path_arr)==1){
                return false;
            }
            $image_path=$image_path_arr[1];
            //保存原图
            if(file_exists($image_absolute_path)){
                $image_para=$this->imagickTool->getImgParam($image_absolute_path);
                if(!empty($image_para)){
                    $img_id=ImagickTool::only_no();
                    $image['img_id']=$img_id;
                    $image['width']=$image_para['width'];
                    $image['height']=$image_para['height'];
                    $image['img_md5']=$image_para['md5'];
                    $image['img_in_url']=$image_path;
                    $md5=$image_para['md5'];
                    $img=self::getImgObjInDBByMd5($md5);
                    if(empty($img)){
                        $save_res1=self::saveImgToDb($image);
                    }else{
//                         self::delFileByFilePath($image_absolute_path);
                        $image_path=isset($img->img_in_url)?$img->img_in_url:'';
                    }
                    return $image_path;
                }
            }
            return $image_path;
        }catch (\Exception $e){
            Log::info($e);
            return '';
        }
    }
    /****
     * 存储图片并获取图片URL
     * @param $img_file
     * @param int $path
     * @return string
     */
    public function imgSaveAndReturnImgUrl($img_file,$path=2){
        try{
            $img_id=$this->imgSave($img_file,2,1);
            if(!empty($img_id)){
                $img_in_url=self::getImgUrlByImgId($img_id);
                return $img_in_url;
            }
            return '';
        }catch (\Exception $e){
            Log::info($e);
            return '';
        }
    }
    /***
     * 查看images表中是不是存储相同的图片
     * @param $md5
     * @return bool
     */
    public static function imgExistInDBByMd5($md5){
        if(empty($md5)){
            return false;
        }
        $num=DB::table('images')->where(array('state'=>1,'img_md5'=>$md5))->count();
        return ($num==0)?false:true;
    }
    /***
     * 图片存入数据库
     * @param array $image
     * @return bool
     */
    private function saveImgToDb(array $image)
    {
        try{
            $image['created_at']=time();
            DB::beginTransaction();
            $num = DB::table('images')->insert($image);
            return ($num==1)?true:false;
        }catch (\Exception $e){
            DB::rollback();
            Log::info($e);
            return false;
        }finally{
            DB::commit();
        }
    }

    /***
     * 静态
     * @param array $image
     * @return bool
     */
    private static function stateFuncSaveImgToDb(array $image)
    {
        try{
            $image['created_at']=time();
            DB::beginTransaction();
            $num = DB::table('images')->insert($image);
            return ($num==1)?true:false;
        }catch (\Exception $e){
            DB::rollback();
            Log::info($e);
            return false;
        }finally{
            DB::commit();
        }
    }
    /***
     * md5获取图片
     * @param $md5
     * @return null
     */
    public static function getImgObjInDBByMd5($md5){
        if(empty($md5)){
            return null;
        }
        $image=DB::table('images')->where(array('state'=>1,'img_md5'=>$md5))->first();
        return $image;
    }

    /****
     * 图片Id获取图片对象
     * @param $img_id
     * @return null
     */
    public static function getImgObjByImgId($img_id){
        if(empty($img_id)){
            return null;
        }
        $image=DB::table('images')->where(array('state'=>1,'img_id'=>$img_id))->first();
        return $image;
    }

    /***
     * 图片压缩并返回图片管理后的图片相对地址
     * @param $image_path
     * @return string
     */
    private function imgPathPngquantAndReturnImgPath($image_path){
    try{
        $image_absolute_path=public_path("images/".$image_path);
        if(!file_exists($image_absolute_path)){
            return $image_path;
        }
        $quality_compression_img_path=ImgTool::pngquantImgCompression($image_absolute_path);
        if(!empty($quality_compression_img_path)){
            $quality_compression_img_absolute_path=public_path("images/".$quality_compression_img_path);
            $file_md5=md5_file($quality_compression_img_absolute_path);
            $img=ImgTool::getImgObjInDBByMd5($file_md5);
            if(!empty($img)){
                $image_path=$img->img_in_url;
            }else{
                $extension=ImagickTool::getImageExtByStateFun($quality_compression_img_absolute_path);
                $img_absolute_path_arr=explode('/images/',$quality_compression_img_absolute_path);
                $img_absolute_path_arr_size=sizeof($img_absolute_path_arr);
                $img_path=$img_absolute_path_arr[$img_absolute_path_arr_size-1];
                $folder_name_arr=explode('/',$img_path);
                $md5_file_name=$folder_name_arr[0].DIRECTORY_SEPARATOR.$file_md5."." . $extension;
                $md5_file_absolute_path=public_path("images/".$md5_file_name);
                rename($quality_compression_img_absolute_path,$md5_file_absolute_path);
                self::saveImgToDbByImgPath($md5_file_name);
                $image_path=$md5_file_name;
            }
        }
        return $image_path;
    }catch (\Exception $e){
        Log::info($e);
        return $image_path;
    }
    }
    /****
     * 图片Id获取图片存储相对地址
     * @param $img_id
     * @return string
     */
    private  function getImgInUrlByImgId($img_id){
        if(empty($img_id)){
            return '';
        }
        $img_in_url=DB::table('images')->where(array('state'=>1,'img_id'=>$img_id))->pluck('img_in_url');
        return $img_in_url;
    }

    /***
     * 判断图片是否在数据库中存过
     * @param $img_in_url
     * @return bool
     */
    private  static function imgExistByImgInUrl($img_in_url){
        if(empty($img_in_url)){
            return false;
        }
        $num=DB::table('images')->where(array('state'=>1,'img_in_url'=>$img_in_url))->count();
        return ($num>0)?true:false;
    }
    /***
     * 图片Md5获取图片Id
     * @param $img_md5
     * @return string
     */
    public  function getImgIdByMd5($img_md5){
        if(empty($img_md5)){
            return '';
        }
        $img_id=DB::table('images')->where(array('state'=>1,'img_md5'=>$img_md5))->pluck('img_id');
        return empty($img_id)?'':$img_id;
    }

    /****
     * 根据图片Id获取图片外部访问链接
     * @param $img_id
     * @return string
     */
    public static function getImgUrlByImgId($img_id){
        if(empty($img_id)){
            return '';
        }
        $img_in_url=self::getImgInUrlByImgId($img_id);
        $img_url=empty($img_in_url)?'':self::$img_url_std_prefix.$img_in_url;
        return $img_url;
    }

    /***
     * 根据图片Id获取图片存储绝对路径
     * @param $img_id
     * @return string
     */
    public static function getImgSavePathByImgId($img_id){
        if(empty($img_id)){
            return '';
        }
        $img_in_url=self::getImgInUrlByImgId($img_id);
        $save_path=empty($img_in_url)?'':self::$img_storage_dir.$img_in_url;
        return $save_path;
    }
    /****
     * 文件绝对地址删除文件
     * @param $file_path
     * @return bool
     */
    private  function delFileByFilePath($file_path)
    {
        try{
            if(!file_exists($file_path)){
                return false;
            }
            unlink($file_path);
            return true;
        }catch (\Exception $e){
            return false;
        }
    }

    /***
     * 图片存储相对路径获取图片URL
     * @param $img_path
     * @return string
     */
    public static function getImgUrlByImgPath($img_path)
    {
        $img_absolute_path=self::$img_storage_dir.$img_path;
        $img_url=self::$img_url_std_prefix.$img_path;
//        if(!file_exists($img_absolute_path)){
//            return '';
//        }
        return trim($img_url);
    }
    public static function getImgCDNUrlByImgPath($img_path)
    {
        $APP_ENV=env('APP_ENV');
        if(trim($APP_ENV)=='local'){
            $img_url=self::$img_url_std_prefix.$img_path;
        }else{
            $img_url=self::$MYTEE_IMG_CDN_PREFIX.$img_path.self::$X_OSS_PROCESS;
        }
        return trim($img_url);
    }
    public static function getProductThumbImgCDNUrlByImgPath($img_path)
    {
        $APP_ENV=env('APP_ENV');
        if(trim($APP_ENV)=='local'){
            $img_url=self::$img_url_std_prefix.$img_path;
        }else{
            $img_url=self::$MYTEE_IMG_CDN_PREFIX.$img_path.self::$PRODUT_THUMB_X_OSS_PROCESS;
        }
        return trim($img_url);
    }
    /****
     * 根据相对路径生成缩略图并并把对应信息保存到数据库中
     * @param $img_path
     * @param int $w
     * @param int $h
     * @return string
     */
    public  function getImgThumbByImgPath($img_path,$w=100,$h=100,$quality_compression=true)
    {
        if(empty($img_path)){
            return '';
        }
        $img_absolute_path=self::$img_storage_dir.$img_path;
        if(!file_exists($img_absolute_path)){
            return '';
        }
        $thumb_path=$this->imagickTool->img2ThumbByImgPath($img_path,$w,$h,$quality_compression);
        if(!empty($thumb_path)){
            self::saveImgToDbByImgPath($thumb_path);
            return $thumb_path;
        }
        return '';
    }

    /***
     * 图片链接转换成图片存储相对路径
     * @param $img_url
     * @return string
     */
    public  static function getImgPathByImgUrl($img_url)
    {
        if(empty($img_url)){
            return '';
        }
        $img_url_arr=explode('/images/',$img_url);
        if(sizeof($img_url_arr)==2){
            return $img_url_arr[1];
        }
        return '';
    }

    /***
     * 获取图片存储绝对地址
     * @param $img_path
     * @return string
     */
    public  static function getImgStoreAbsolutePathByImgPath($img_path)
    {
        if(empty($img_path)){
            return '';
        }
        $img_absolute_path=self::$img_storage_dir.$img_path;
//        if(!file_exists($img_absolute_path)){
//            return '';
//        }
        return $img_absolute_path;
    }
    /***
     * 保存图片到数据到数据库
     * @param $img_path
     * @return string
     */
    public static function saveImgToDbByImgPath($img_path){
        try{
            $img_absolute_path=self::$img_storage_dir.$img_path;
            if(!file_exists($img_absolute_path)){
                return '';
            }
            if(file_exists($img_absolute_path)){
                $image_para=ImagickTool::getImgParamByStateFuncAndImgPath($img_absolute_path);
                if(!empty($image_para)){
                    $image['width']=isset($image_para['width'])?$image_para['width']:0;
                    $image['height']=isset($image_para['height'])?$image_para['height']:0;
                    $image['img_md5']=$image_para['md5'];
                    $image['img_in_url']=$img_path;
                    $img=self::getImgObjInDBByMd5($image_para['md5']);
                    if(empty($img)){
                        $save_res1=self::stateFuncSaveImgToDb($image);
                    }else{
                        $img_relative_path=self::getImgPathByImgUrl($img_absolute_path);//拆分绝对地址
                        //如果存储过该图片，有图片的存储地址不一样，删除当前重复图片存储地址
                        $img_relative_path_arr=explode(DIRECTORY_SEPARATOR,$img_relative_path);
                        $img_in_url_arr=explode(DIRECTORY_SEPARATOR,$img->img_in_url);
                        $img_path=isset($img->img_in_url)?$img->img_in_url:'';
                    }
                }
            }else{
                $img_path='';
            }
            return $img_path;
        }catch (\Exception $e){
            Log::info($e);
            return '';
        }

    }

    /***
     * 保存色块
     * @param $color_code  十六进制颜色编码
     * @return string
     */
    public function  saveColorBlock($color_code){
        $color_code = str_replace("#", "", $color_code);
        $folder=date('Ym');
//            文件夹绝对路径
        $folder_path=self::$img_storage_dir.$folder;
        @$this->imagickTool->mkFolder($folder_path);
        //生成图片名
        $newName = md5(date('ymdhis').rand(1, 1000)) .  ".png";
        $file_absolute_path=$folder_path.DIRECTORY_SEPARATOR.$newName;
        $file_path=$folder.DIRECTORY_SEPARATOR.$newName;
        $img = imagecreate(128, 128);
        //给图片分配颜色
        $rgb = self::hex2rgb($color_code);
        imagecolorallocate($img ,$rgb['r'],$rgb['g'],$rgb['b']);
        imagepng($img,$file_absolute_path);
        $save_path=self::saveImgToDbByImgPath($file_path);
        return $save_path;
    }
    /**
     * 16进制颜色转RGB
     * @param $hex
     * @return array
     */
    function hex2rgb($hex)
    {
        $hex = str_replace("#", "", $hex);

        if (strlen($hex) == 3) {
            $r = hexdec(substr($hex, 0, 1) . substr($hex, 0, 1));
            $g = hexdec(substr($hex, 1, 1) . substr($hex, 1, 1));
            $b = hexdec(substr($hex, 2, 1) . substr($hex, 2, 1));
        } else {
            $r = hexdec(substr($hex, 0, 2));
            $g = hexdec(substr($hex, 2, 2));
            $b = hexdec(substr($hex, 4, 2));
        }

        return array('r'=>$r, 'g'=>$g,'b'=> $b);
    }

    /***
     * 判断图片链接是否有效
     * @param $image_url
     * @return bool
     */
    public static function imageUrlIsValid($image_url)
    {
        if(empty($image_url)){
            return false;
        }
        $img_path=self::getImgPathByImgUrl($image_url);
        if(empty($img_path)){
            return false;
        }
        $img_absolute_path=self::$img_storage_dir.$img_path;
//        if(!file_exists($img_absolute_path)){
//            return false;
//        }
        $img_exist=self::imgExistByImgInUrl($img_path);
        return $img_exist;
    }

    /****
     * pngquant压缩图片
     * @param string $quality
     * @param $img_path  图片绝对路径
     * @return bool|string
     */
    public static function pngquantImgCompression($img_path,$quality='60-80'){
      try{
          $pngquant_exe=env('PNGQUANT_EXE');
          if(!file_exists($img_path)){
              return '';
          }
          $img_ext=ImagickTool::getImageExtByStateFun($img_path);
          if($img_ext!='png'){
              return '';
          }
          $pngquant_shell=$pngquant_exe.' -s 1 --quality='.$quality.' '.$img_path;
          @shell_exec($pngquant_shell);
          $img_path_arr=explode('.',$img_path);
          if(sizeof($img_path_arr)<=1){
              return '';
          }
          if(sizeof($img_path_arr)==4){
              $new_absolute_img_path=$img_path_arr[0].'.'.$img_path_arr[1].'.'.$img_path_arr[2].'-fs8.'.$img_path_arr[3];
          }else{
              $new_absolute_img_path=$img_path_arr[0].'-fs8.'.$img_path_arr[1];
          }
          if(!file_exists($new_absolute_img_path)){
              return '';
          }
          $new_img_path_arr=explode('/images/',$new_absolute_img_path);
          return (sizeof($new_img_path_arr)==2)?$new_img_path_arr[1]:'';
      }catch (\Exception $e){
         Log::info($e);
        return '';
      }
    }
    /**
     * 数据验证
     * @param Request $request
     * @param $check_data
     * @return mixed
     */
    public static function store(Request $request,$check_data)
    {
        $v = Validator::make($request->all(), $check_data);
        return $v;
    }
}
class Str{}

